<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>FormData</title>
	</head>
	<body>
		<!-- FormData 发送 HTML 表单：带有或不带文件，带有其他字段等。 -->

		<script>
			// 构造函数语法是：
			// 如果提供了 HTML form 元素，它会自动捕获 form 元素字段。

			// let FormData = new FormData([form])

			// FormData 的特殊之处在于网络方法，例如 fetch 可以接受一个 FormData 对象作为 body（请求体）。它会被编码并发送出去，带有 Content-Type: multipart/form-data。
			// 从服务器的角度来看，它就像一个普通的表单提交。
		</script>

		<!-- **************************************************************************************************************************************************** -->

		<form id="formElem">
			<input type="text" name="name" value="John" />
			<input type="text" name="surname" value="Smith" />
			<input type="file" name="file" value="Smith" />
			<input type="submit" />
		</form>

		<script>
			// 发送一个简单的表单
			formElem.onsubmit = async (e) => {
				e.preventDefault()

				let response = await fetch('request-url', {
					method: 'POST',
					body: new FormData(formElem), // 自动捕获 form 元素字段，类似于普通的表单提交
				})

				let result = await response.json()
			}
		</script>

		<!-- **************************************************************************************************************************************************** -->

		<script>
			// FormData 方法
			const formData = new FormData()

			// 我们可以从 HTML 表单创建 new FormData(form)，也可以创建一个完全没有表单的对象，然后使用以下方法附加字段：

			formData.append(name, value) // 添加具有给定 name 和 value 的表单字段
			formData.append(name, blob / file, fileName) // 添加一个字段，就像它是 <input type="file"> 第三个参数 fileName 设置文件名（而不是表单名），因为它是用户文件系统中文件的名称。
			formData.delete(name) // 移除带有给定 name 的字段，
			formData.get(name) // 获取带有给定 name 的字段值，
			formData.has(name) // 如果存在带有给定 name 的字段，则返回 true，否则返回 false。

			// 从技术上来讲，一个表单可以包含多个具有相同 name 的字段，因此，多次调用 append 将会添加多个具有相同名称的字段。
			// 还有一个 set 方法，语法与 append 相同。不同之处在于 .set 移除所有具有给定 name 的字段，然后附加一个新字段。
			// 因此，它确保了只有一个具有这种 name 的字段，其他的和 append 一样。
		</script>
	</body>
</html>
